package com.hxgz.steel.service.Impl;

import com.alipay.api.AlipayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.alipay.demo.trade.utils.ZxingUtils;
import com.google.common.collect.Maps;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.hxgz.steel.common.Const;
import com.hxgz.steel.common.ServerResponse;
import com.hxgz.steel.config.WeChatConfig;
import com.hxgz.steel.dao.*;
import com.hxgz.steel.domain.*;
import com.hxgz.steel.dto.PayOrderItemDto;
import com.hxgz.steel.service.OrderService;
import com.hxgz.steel.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Service("orderService")
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private PayInfoMapper payInfoMapper;
    @Autowired
    private ProductModelMapper productModelMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WeChatConfig weChatConfig;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private QuotationMapper quotationMapper;
    @Autowired
    private IntegralMapper integralMapper;
    @Autowired
    private SocerManagerMapper socerManagerMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private QuotationInfoMapper qiMapper;
    @Autowired
    public OSSClientUtil ossutil;

    private static AlipayTradeService tradeService;

    static {

        /** 一定要在创建AlipayTradeService之前调用Configs.init()设置默认参数
         *  Configs会读取classpath下的zfbinfo.properties文件配置信息，如果找不到该文件则确认该文件是否在classpath目录
         */
        Configs.init("zfbinfo.properties");

        /** 使用Configs提供的默认参数
         *  AlipayTradeService可以使用单例或者为静态成员对象，不需要反复new
         */
        tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
    }

    @Override
    @Transactional
    public ServerResponse pay(String orderNo, Long userId, String path, String ip) throws Exception {
        Map<String, String> resultMap = Maps.newHashMap();
        Order order = orderMapper.selectByUserIdAndOrderNo(orderNo, userId);
        if (order == null) {
            return ServerResponse.createByErrorMessage("用户没有该订单");
        }
        resultMap.put("orderNo", String.valueOf(order.getOrderNo()));

        // (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
        // 需保证商户系统端不能重复，建议通过数据库sequence生成，
        String outTradeNo = order.getOrderNo();

        // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
        String subject = new StringBuilder().append("风水网扫码支付,订单号:").append(outTradeNo)
                .toString();

        // (必填) 订单总金额，单位为元，不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        String totalAmount = order.getPayment().toString();

        // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0";

        // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
        // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
        String sellerId = "";

        // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
        String body = new StringBuilder().append("订单").append(outTradeNo).append("购买商品共")
                .append(totalAmount).append("元").toString();

        // 商户操作员编号，添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        //extendParams.setSysServiceProviderId("2088100200300400500");
        extendParams.setSysServiceProviderId("2088431372291329");

        // 支付超时，定义为45分钟
        String timeoutExpress = "45m";

        // 商品明细列表，需填写购买商品详细信息，
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();

        List<OrderItem> orderItemList = orderItemMapper.getByOrderNoUserId(orderNo, userId);
        if(order.getQuotationId()==null){
            for (OrderItem orderItem : orderItemList) {
                GoodsDetail goods = GoodsDetail
                        .newInstance(orderItem.getProductId().toString(), orderItem.getProductName(),
                                BigDecimalUtil
                                        .mul(orderItem.getCurrentUnitPrice().doubleValue(), new Double(100).doubleValue())
                                        .longValue(),
                                orderItem.getQuantity());
                goodsDetailList.add(goods);
            }
        }


        // 创建扫码支付请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl(
                        PropertiesUtil.getProperty("alipay.callback.url"))//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                .setGoodsDetailList(goodsDetailList);

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝预下单成功: )");

                AlipayTradePrecreateResponse response = result.getResponse();
                dumpResponse(response);

                File folder = new File(path);
                if (!folder.exists()) {
                    folder.setWritable(true);
                    folder.mkdirs();
                }

                // 需要修改为运行机器上的路径
                //细节细节细节
                String qrPath = String.format(path + "/qr-%s.png", response.getOutTradeNo());
                String qrFileName = String.format("qr-%s.png", response.getOutTradeNo());
                ZxingUtils.getQRCodeImge(response.getQrCode(), 256, qrPath);
                File targetFile = new File(path, qrFileName);
                String ZFBUrl = "";
                try {
                    FileInputStream fileInputStream = new FileInputStream(targetFile);
                    MultipartFile multipartFile = new MockMultipartFile(targetFile.getName(),
                            targetFile.getName(),
                            ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
                    String name = ossutil.uploadImg2Oss(multipartFile);
                    ZFBUrl = ossutil.getImgUrl(name);
//          return ServerResponse.createBySuccess(imgurl);
//          UploadPic uploadPic = new UploadPic();
//          ZFBUrl = uploadPic.upload(multipartFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    log.error("上传二维码异常", e);
                } catch (IOException e) {
                    e.printStackTrace();
                    log.error("上传二维码异常", e);
                }
        /*try {
          FTPUtil.uploadFile(Lists.newArrayList(targetFile));
        } catch (IOException e) {
          log.error("上传二维码异常", e);
        }*/
       /* log.info("qrPath:" + qrPath);
        File file = new File(uploadName);
        String fileName = file.getName();
        String ZFBUrl = PropertiesUtil.getProperty("file.server.peal") + fileName;*/
                String WxUrl = "";

                /* 微信支付*/
                SortedMap<String, String> sortedMap = new TreeMap<>();
                sortedMap.put("appid", weChatConfig.getAppId());
                sortedMap.put("mch_id", weChatConfig.getMchId());
                sortedMap.put("nonce_str", CommonUtils.generateUUID());
                sortedMap.put("body", order.getMerchantName());
                sortedMap.put("out_trade_no", order.getOrderNo());
                sortedMap.put("total_fee",
                        String.valueOf(order.getPayment().multiply(new BigDecimal(100)).intValue()));
                sortedMap.put("spbill_create_ip", ip);
                sortedMap.put("notify_url", weChatConfig.getPayCallbackUrl());
                sortedMap.put("trade_type", "NATIVE");
                //sign 签名
                String sign = WXPayUtil.createSign(sortedMap, weChatConfig.getKey());
                sortedMap.put("sign", sign);
                //参数转xml
                String payxml = WXPayUtil.mapToXml(sortedMap);
                //统一下单地址
                String orderStr = HttpTools.doPost(WeChatConfig.getUnifiedOrderUrl(), payxml, 4000);
                Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
                if (unifiedOrderMap != null) {
                    try {
                        String codeUrl = unifiedOrderMap.get("code_url");
                        //生成二维码
                        HashMap<EncodeHintType, Object> hints = new HashMap<>();
                        //设置纠错等级
                        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
                        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                        BitMatrix bitMatrix = new MultiFormatWriter()
                                .encode(codeUrl, BarcodeFormat.QR_CODE, 400, 400, hints);
                        File Wxfile = new File(
                                (PropertiesUtil.getProperty("ftp.server.http.prefix") + PropertiesUtil
                                        .getProperty("ftp.server.imgPath")),
                                order.getOrderNo().toString() + "wx" + ".png");
                        MatrixToImageWriter.writeToPath(bitMatrix, "png", Wxfile.toPath());
                        FileInputStream fileInputStream = new FileInputStream(Wxfile);
                        MultipartFile multipartFile = new MockMultipartFile(Wxfile.getName(),
                                Wxfile.getName(),
                                ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
                        String name = ossutil.uploadImg2Oss(multipartFile);
                        WxUrl = ossutil.getImgUrl(name);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    throw new NullPointerException();
                }
                resultMap.put("ZFBqrUrl", ZFBUrl);
                resultMap.put("WxUrl", WxUrl);
                return ServerResponse.createBySuccess(resultMap);
            case FAILED:
                log.error("支付宝预下单失败!!!");
                return ServerResponse.createByErrorMessage("支付宝预下单失败!!!");

            case UNKNOWN:
                log.error("系统异常，预下单状态未知!!!");
                return ServerResponse.createByErrorMessage("系统异常，预下单状态未知!!!");

            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                return ServerResponse.createByErrorMessage("不支持的交易状态，交易返回异常!!!");
        }
    }

    // 简单打印应答
    private void dumpResponse(AlipayResponse response) {
        if (response != null) {
            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
            if (StringUtils.isNotEmpty(response.getSubCode())) {
                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
                        response.getSubMsg()));
            }
            log.info("body:" + response.getBody());
        }
    }

    @Override
    @Transactional
    public ServerResponse aliCallback(Map<String, String> params) throws Exception {
        String orderNo = params.get("out_trade_no");
        String tradeNo = params.get("trade_no");
        String tradeStatus = params.get("trade_status");
        Order order = orderMapper.selectByOrderNo(orderNo);
        int isOrder = 0;
        if (order == null) {
            return ServerResponse.createByErrorMessage("非风水商城的订单,回调忽略");
        }
        if (order.getStatus() >= Const.OrderStatusEnum.PAID.getCode()) {
            return ServerResponse.createBySuccess("支付宝重复调用");
        }
        if (Const.AlipayCallback.TRADE_STATUS_TRADE_SUCCESS.equals(tradeStatus)) {
            order.setPaymentTime(DateTimeUtil.strToDate(params.get("gmt_payment")));
            order.setStatus(Const.OrderStatusEnum.PAID.getCode());
            order.setStatusSeller(Const.OrderStatusEnum.PAID.getCode());
            order.setCreateTime(new Date());
            order.setUpdateTime(new Date());
            isOrder = orderMapper.updateByPrimaryKeySelective(order);
        }
        PayInfo payInfo = new PayInfo();
        payInfo.setUserId(order.getUserId());
        payInfo.setOrderNo(order.getOrderNo());
        payInfo.setPayPlatform(1);//支付宝支付
        payInfo.setPlatformNumber(tradeNo);
        payInfo.setPlatformStatus(tradeStatus);
        int isPay = payInfoMapper.insert(payInfo);
        //积分增加
        User user = userMapper.selectByPrimaryKey(order.getUserId());    //获取订单对应的用户数据
        Long integralId = Long.valueOf(3);
        SocerManager socerManager = socerManagerMapper.selectByPrimaryKey(integralId); //获取对应的分数信息
        if (socerManager.getStatus().equals(1)) {
            int oldScore = user.getScore();//原有积分
            BigDecimal bd = new BigDecimal(socerManager.getSocer());
            int addScore = order.getPayment().multiply(bd).intValue();   //需要添加的积分
            int newScore = oldScore + addScore; //添加后的积分
            user.setScore(newScore);          //用户新增后的积分
            int userSuccess = userMapper.updateByPrimaryKeySelective(user); //更新用户数据
            Integral integral = new Integral();
            integral.setUserId(order.getUserId());
            integral.setInSource(integralId);
            integral.setType(0);
            integral.setInChange(addScore);
            int isSuccess = integralMapper.insertSelective(integral);  //插入积分明细
            if (isPay < 1 || userSuccess < 1 || isSuccess < 1) {
                throw new Exception();
            }
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse queryOrderPayStatus(Long userId, String orderNo) {
        Order order = orderMapper.selectByUserIdAndOrderNo(orderNo, userId);
        if (order == null) {
            return ServerResponse.createByErrorMessage("用户没有该订单");
        }
        if (order.getStatus() >= Const.OrderStatusEnum.PAID.getCode()) {
            return ServerResponse.createBySuccess();
        }
        return ServerResponse.createByError();
    }

    @Override
    @Transactional
    public ServerResponse addOrder(Order order, PayOrderItemDto payOrderItemDto) {
        Merchant merchant = merchantMapper.selectByPrimaryKey(order.getMerchantId());
        if (merchant != null) {
            order.setMerchantName(merchant.getName());
        }
        //判断店铺是否自营
        if (order.getMerchantId() != 1) {
            order.setSelfSupport(0);
        } else {
            order.setSelfSupport(1);
        }

        //后台查询商品单价和总价
        Map map = Maps.newHashMap();
        if (payOrderItemDto.getColor() != null && payOrderItemDto.getType() != null) {
            map.put("productId", payOrderItemDto.getProductId());
            map.put("model", payOrderItemDto.getType());
            map.put("color", payOrderItemDto.getColor());
            Product product = productMapper.getProductById(payOrderItemDto.getProductId());
            //运费
            if (product.getFreight() == null || "".equals(product.getFreight())) {
                product.setFreight(new BigDecimal(0));
            }
            //税点
            if (product.getTaxPoint() == null || "".equals(product.getTaxPoint())) {
                product.setTaxPoint(new BigDecimal("0"));
            }

            BigDecimal totalPrice = new BigDecimal(0);
            BigDecimal price = new BigDecimal(0);
            List<ProductModel> priceByKind = productModelMapper.getPriceByKind(map);

            //数量
            Integer quantity = payOrderItemDto.getQuantity();
            //总运费
            BigDecimal totalFreight = new BigDecimal(0);

            if (priceByKind.size() > 0) {
                //单价
                price = priceByKind.get(0).getPrice();
                if (product.getFreight() == null || "".equals(product.getFreight())) {
                    product.setFreight(new BigDecimal(0));
                }
                if (new Integer(0).equals(product.getFreightStatus())) {
                    if (Double.valueOf(product.getFreight().toString()) > 0) {
                        totalFreight = BigDecimalUtil
                                .mul(product.getFreight().doubleValue(), quantity.doubleValue());
                    }
                } else {
                    if (Double.valueOf(product.getFreight().toString()) > 0) {
                        totalFreight = product.getFreight();
                    }
                }

                BigDecimal total = BigDecimalUtil.mul(price.doubleValue(), quantity.doubleValue());
                BigDecimal taxation = BigDecimalUtil
                        .mul(total.doubleValue(), product.getTaxPoint().doubleValue());

                BigDecimal totalPrice1 = BigDecimalUtil
                        .add(total.doubleValue(), totalFreight.doubleValue());
                totalPrice = BigDecimalUtil.add(totalPrice1.doubleValue(), taxation.doubleValue());
            }
            //初始化佣金数
            BigDecimal brokerage = new BigDecimal(0);
            if (merchant != null) {
                //佣金比列数
                String commission = merchant.getCommission();
                BigDecimal cn = new BigDecimal(0);
                if (StringUtils.isNotBlank(commission)) {
                    cn = new BigDecimal(commission);
                }
                BigDecimal percentage = new BigDecimal(100);
                //获得的百分比
                BigDecimal div = cn.divide(percentage);
                //获得的佣金实际数据
                brokerage=div.multiply(totalPrice);
            }
            //提交订单
            order.setOrderNo(CommonUtils.generateUUID());
            order.setMoney(totalPrice);
            order.setPayment(totalPrice);
            order.setPaymentType(1);
            order.setPostage(totalFreight);
            order.setStatus(Const.OrderStatusEnum.NO_PAY.getCode());
            order.setStatusSeller(Const.OrderStatusEnum.NO_PAY.getCode());
            order.setBrokerage(brokerage);

            if (orderMapper.insertSelective(order) > 0) {
                OrderItem orderItem = new OrderItem();
                orderItem.setOrderId(order.getId());
                orderItem.setUserId(order.getUserId());
                orderItem.setProductId(payOrderItemDto.getProductId());
                orderItem.setType(payOrderItemDto.getType());
                orderItem.setColor(payOrderItemDto.getColor());
                Integer categoryId = product.getCategoryId();
                if (new Integer(1).equals(categoryId)){
                    orderItem.setCategoryName("风类");
                }
                if (new Integer(2).equals(categoryId)){
                    orderItem.setCategoryName("水类");
                }
                if (new Integer(3).equals(categoryId)){
                    orderItem.setCategoryName("电类");
                }
                if (new Integer(4).equals(categoryId)){
                    orderItem.setCategoryName("消防类");
                }
                orderItem.setTopName(product.getTopName());
                orderItem.setMaterials(product.getMaterials());
                orderItem.setFeatures(product.getFeatures());
                orderItem.setUnit(product.getUnit());
                orderItem.setProductName(payOrderItemDto.getProductName());
                orderItem.setCurrentUnitPrice(price);
                orderItem.setTotalPrice(totalPrice);
                orderItem.setQuantity(payOrderItemDto.getQuantity());
                if (payOrderItemDto.getPic() != null) {
                    orderItem.setProductImage(payOrderItemDto.getPic());
                }
                if (orderItemMapper.insertSelective(orderItem) > 0) {
                    Map<String, Object> resultMap = Maps.newHashMap();
                    resultMap.put("orderNo", order.getOrderNo());
                    resultMap.put("orderId", order.getId());
                    return ServerResponse.createBySuccess("保存成功", resultMap);
                }
            }
        } else {
            return ServerResponse.createBySuccessMessage("发现此错误麻烦及时联系陈湃");
        }

        return ServerResponse.createBySuccessMessage("保存失败");
    }

    @Override
    public ServerResponse submitOrder(Order order, PayOrderItemDto payOrderItemDto) {
        Merchant merchant = merchantMapper.selectByPrimaryKey(order.getMerchantId());
        if (merchant != null) {
            order.setMerchantName(merchant.getName());
        }
        //判断店铺是否自营
        if (order.getMerchantId() != 1) {
            order.setSelfSupport(0);
        } else {
            order.setSelfSupport(1);
        }

        //后台查询商品单价和总价
        Map map = Maps.newHashMap();
        /**
         *   WEB前端实单求购调度整理
         */
        //提交订单
        order.setOrderNo(CommonUtils.generateUUID());
        order.setMoney(order.getPayment());
        order.setPaymentType(1);
        order.setStatus(Const.OrderStatusEnum.NO_PAY.getCode());
        order.setStatusSeller(Const.OrderStatusEnum.NO_PAY.getCode());
        if (merchant != null) {
            //佣金比列数
            String commission = merchant.getCommission();
            BigDecimal cn = new BigDecimal(0);
            if (!StringUtils.isEmpty(commission)) {
                cn = new BigDecimal(commission);
            }
            BigDecimal percentage = new BigDecimal(100);
            //获得的百分比
            BigDecimal div = cn.divide(percentage);
            //获得的佣金实际数据
            order.setBrokerage(order.getPayment().multiply(div));
        }

        Long quotationId = order.getQuotationId();//报价id
        List<AskInfo> askInfos = payOrderItemDto.getAskInfos();//求购明细

        ArrayList<Boolean> booleans = new ArrayList<>();
        if (orderMapper.insertSelective(order) > 0) {
            if (CollectionUtils.isNotEmpty(askInfos)) {
                for (AskInfo askInfo : askInfos) {
                    OrderItem orderItem = new OrderItem();
                    orderItem.setOrderId(order.getId());
                    orderItem.setUserId(order.getUserId());
                    QuotationInfo quotationInfo = qiMapper.selectByQuotationIdAndAskInfoId(askInfo.getId(), quotationId);
                    orderItem.setProductName(askInfo.getProductName());
                    if (quotationInfo != null) {
                        orderItem.setCurrentUnitPrice(quotationInfo.getPrice());
                    }
                    orderItem.setTotalPrice(order.getPayment());
                    orderItem.setQuantity(Integer.valueOf(askInfo.getQuantity()));
                    int i = orderItemMapper.insertSelective(orderItem);
                    if (i > 0) {
                        booleans.add(true);
                    } else {
                        booleans.add(false);
                    }
                }
            } else {
                OrderItem orderItem = new OrderItem();
                orderItem.setOrderId(order.getId());
                orderItem.setUserId(order.getUserId());
                orderItem.setTotalPrice(order.getPayment());
                int i = orderItemMapper.insertSelective(orderItem);
                if (i > 0) {
                    booleans.add(true);
                } else {
                    booleans.add(false);
                }
            }

            boolean flag = true;
            for (Boolean aBoolean : booleans) {
                if (!aBoolean) {
                    flag = false;
                }
            }
            if (flag) {
                Map<String, Object> resultMap = Maps.newHashMap();
                resultMap.put("orderNo", order.getOrderNo());
                resultMap.put("orderId", order.getId());
                return ServerResponse.createBySuccess("保存成功", resultMap);
            }
        }
        return ServerResponse.createByErrorMessage("失败");
    }

    @Override
    @Transactional
    public ServerResponse wxPay(Long id, String merchantId, String quotationId, String addressId,
                                Integer invoice, String remark, String ip, HttpServletResponse response)
            throws Exception {
        Order order = new Order();
        order.setOrderNo(CommonUtils.generateUUID());
        order.setMerchantId(Long.valueOf(merchantId));
        Merchant merchant = merchantMapper.selectByPrimaryKey(Long.valueOf(merchantId));
        order.setMerchantName(merchant.getName());
        order.setQuotationId(Long.valueOf(quotationId));
        order.setAddressId(Long.valueOf(addressId));
        order.setUserId(id);
        Quotation quotation = quotationMapper.selectByPrimaryKey(Long.valueOf(quotationId));
        order.setMoney(quotation.getTotalPrice());
        order.setPayment(quotation.getTotalPrice());
        order.setPostage(quotation.getFreight());
        order.setStatus(0);
        order.setInvoice(invoice);
        if (merchant.getId() == 1) {
            order.setSelfSupport(1);
        } else {
            order.setSelfSupport(0);
        }
        order.setBrokerage(new BigDecimal(merchant.getCommission()));
        order.setRemark(remark);
        orderMapper.insertSelective(order);
        //生成签名
        SortedMap<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("appid", weChatConfig.getAppId());
        sortedMap.put("mch_id", weChatConfig.getMchId());
        sortedMap.put("nonce_str", CommonUtils.generateUUID());
        sortedMap.put("body", order.getMerchantName());
        sortedMap.put("out_trade_no", order.getOrderNo());
        sortedMap.put("total_fee",
                String.valueOf(order.getPayment().multiply(new BigDecimal(100)).intValue()));
        sortedMap.put("spbill_create_ip", ip);
        sortedMap.put("notify_url", weChatConfig.getPayCallbackUrl());
        sortedMap.put("trade_type", "NATIVE");
        //sign 签名
        String sign = WXPayUtil.createSign(sortedMap, weChatConfig.getKey());
        sortedMap.put("sign", sign);
        //参数转xml
        String payxml = WXPayUtil.mapToXml(sortedMap);
        //统一下单地址
        String orderStr = HttpTools.doPost(WeChatConfig.getUnifiedOrderUrl(), payxml, 4000);
        Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
        if (unifiedOrderMap != null) {
            try {
                String codeUrl = unifiedOrderMap.get("code_url");
                //生成二维码
                HashMap<EncodeHintType, Object> hints = new HashMap<>();
                //设置纠错等级
                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
                hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                BitMatrix bitMatrix = new MultiFormatWriter()
                        .encode(codeUrl, BarcodeFormat.QR_CODE, 400, 400, hints);
                File file = new File((PropertiesUtil.getProperty("ftp.server.http.prefix") + PropertiesUtil
                        .getProperty("ftp.server.imgPath")), order.getOrderNo().toString() + ".png");
                MatrixToImageWriter.writeToPath(bitMatrix, "png", file.toPath());
                String qrUrl = PropertiesUtil.getProperty("file.server.peal") + file.getName();
                return ServerResponse.createBySuccess(qrUrl);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            throw new NullPointerException();
        }

        return ServerResponse.createBySuccess();
    }

    @Override
    public Order getByOrderNo(String outTradeNo) {
        Order order = orderMapper.getOrderByOrderNo(outTradeNo);
        return order;
    }

    @Override
    @Transactional
    public ServerResponse updateOrder(Order order) throws Exception {
        int orderSuccess = orderMapper.updateByPrimaryKeySelective(order);
        //添加积分 获取订单对应的用户数据
        User user = userMapper.selectByPrimaryKey(order.getUserId());
        Long integralId = Long.valueOf(3);
        //获取对应的分数信息
        SocerManager socerManager = socerManagerMapper.selectByPrimaryKey(integralId);
        if (socerManager.getStatus().equals(1)) {
            //原有积分
            int oldScore = user.getScore();
            BigDecimal bd = new BigDecimal(socerManager.getSocer());
            //需要添加的积分
            int addScore = order.getPayment().multiply(bd).intValue();
            //添加后的积分
            int newScore = oldScore + addScore;
            //用户新增后的积分
            user.setScore(newScore);
            //更新用户数据
            int userSuccess = userMapper.updateByPrimaryKeySelective(user);
            Integral integral = new Integral();
            integral.setUserId(order.getUserId());
            integral.setInSource(integralId);
            integral.setType(0);
            integral.setInChange(addScore);
            //插入积分明细
            int isSuccess = integralMapper.insertSelective(integral);
            PayInfo payInfo = new PayInfo();
            payInfo.setUserId(order.getUserId());
            payInfo.setOrderNo(order.getOrderNo());
            //微信支付
            payInfo.setPayPlatform(2);
            //uuid代替流水号码
            payInfo.setPlatformNumber(CommonUtils.generateUUID());
            payInfo.setPlatformStatus("SUCCESS");
            //插入支付明細
            int isPayInfo = payInfoMapper.insert(payInfo);
            if (isSuccess < 1 || userSuccess < 1 || orderSuccess < 1 || isPayInfo < 1) {
                throw new Exception();
            }
        }
        return ServerResponse.createBySuccessMessage("支付成功");
    }

    @Override
    public void closeOrders(int hour) {
        Date closeTime = DateUtils.addHours(new Date(), -hour);
        List<Order> toCloseOrderList = orderMapper
                .selectOrderStatusByCreateTime(Const.OrderStatusEnum.NO_PAY.getCode(),
                        DateTimeUtil.dateToStr(closeTime));
        List<Long> ids = new ArrayList<>();

        for (Order toCloseOrder : toCloseOrderList) {
            ids.add(toCloseOrder.getId());
        }
        if (CollectionUtils.isNotEmpty(ids)) {
            orderMapper.updateStatusByIds(ids);
        }

    }

    @Override
    public ServerResponse payExcel(String totalPrice, String path, String ip, Long id,String orderNo)
            throws Exception {
        Map<String, String> resultMap = Maps.newHashMap();
        String orderUuid = CommonUtils.generateUUID();
        // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
        String subject = new StringBuilder().append("风水网扫码支付,订单号:").append(orderUuid)
                .toString();

        // (必填) 订单总金额，单位为元，不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        String totalAmount = totalPrice;

        // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0";

        // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
        // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
        String sellerId = "";

        // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
        String body = new StringBuilder().append("订单").append(orderUuid).append("购买商品共")
                .append(totalAmount).append("元").toString();

        // 商户操作员编号，添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        //extendParams.setSysServiceProviderId("2088100200300400500");
        extendParams.setSysServiceProviderId("2088431372291329");

        // 支付超时，定义为45分钟
        String timeoutExpress = "45m";

        // 商品明细列表，需填写购买商品详细信息，
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();

        /*List<OrderItem> orderItemList = orderItemMapper.getByOrderNoUserId(orderNo, userId);
        for (OrderItem orderItem : orderItemList) {
            GoodsDetail goods = GoodsDetail
                .newInstance(orderItem.getProductId().toString(), orderItem.getProductName(),
                    BigDecimalUtil
                        .mul(orderItem.getCurrentUnitPrice().doubleValue(), new Double(100).doubleValue())
                        .longValue(),
                    orderItem.getQuantity());
            goodsDetailList.add(goods);
        }*/

        // 创建扫码支付请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(orderUuid)
                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl(
                        PropertiesUtil.getProperty("alipay.callback.url"))//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                .setGoodsDetailList(goodsDetailList);

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝预下单成功: )");

                AlipayTradePrecreateResponse response = result.getResponse();
                dumpResponse(response);

                File folder = new File(path);
                if (!folder.exists()) {
                    folder.setWritable(true);
                    folder.mkdirs();
                }

                // 需要修改为运行机器上的路径
                //细节细节细节
                String qrPath = String.format(path + "/qr-%s.png", response.getOutTradeNo());
                String qrFileName = String.format("qr-%s.png", response.getOutTradeNo());
                ZxingUtils.getQRCodeImge(response.getQrCode(), 256, qrPath);
                File targetFile = new File(path, qrFileName);
                String ZFBUrl = "";
                try {
                    FileInputStream fileInputStream = new FileInputStream(targetFile);
                    MultipartFile multipartFile = new MockMultipartFile(targetFile.getName(),
                            targetFile.getName(),
                            ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
                    String name = ossutil.uploadImg2Oss(multipartFile);
                    ZFBUrl = ossutil.getImgUrl(name);
//          return ServerResponse.createBySuccess(imgurl);
//          UploadPic uploadPic = new UploadPic();
//          ZFBUrl = uploadPic.upload(multipartFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    log.error("上传二维码异常", e);
                } catch (IOException e) {
                    e.printStackTrace();
                    log.error("上传二维码异常", e);
                } catch (Exception e) {
                    e.printStackTrace();
                }
        /*try {
          FTPUtil.uploadFile(Lists.newArrayList(targetFile));
        } catch (IOException e) {
          log.error("上传二维码异常", e);
        }*/
       /* log.info("qrPath:" + qrPath);
        File file = new File(uploadName);
        String fileName = file.getName();
        String ZFBUrl = PropertiesUtil.getProperty("file.server.peal") + fileName;*/
                String WxUrl = "";
                /* 微信支付*/
                SortedMap<String, String> sortedMap = new TreeMap<>();
                sortedMap.put("appid", weChatConfig.getAppId());
                sortedMap.put("mch_id", weChatConfig.getMchId());
                sortedMap.put("nonce_str", CommonUtils.generateUUID());
                sortedMap.put("body", orderUuid);
                sortedMap.put("out_trade_no", orderNo);
                sortedMap.put("total_fee", String.valueOf(new BigDecimal(totalPrice).multiply(new BigDecimal(100)).intValue()));
                sortedMap.put("spbill_create_ip", ip);
                sortedMap.put("notify_url", weChatConfig.getPayCallbackUrl());
                sortedMap.put("trade_type", "NATIVE");
                //sign 签名
                String sign = WXPayUtil.createSign(sortedMap, weChatConfig.getKey());
                sortedMap.put("sign", sign);
                //参数转xml
                String payxml = WXPayUtil.mapToXml(sortedMap);
                //统一下单地址
                String orderStr = HttpTools.doPost(WeChatConfig.getUnifiedOrderUrl(), payxml, 4000);
                Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
                if (unifiedOrderMap != null) {
                    try {
                        String codeUrl = unifiedOrderMap.get("code_url");
                        //生成二维码
                        HashMap<EncodeHintType, Object> hints = new HashMap<>();
                        //设置纠错等级
                        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
                        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                        BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 400, 400, hints);
                        File Wxfile = new File(
                                (PropertiesUtil.getProperty("ftp.server.http.prefix") + PropertiesUtil
                                        .getProperty("ftp.server.imgPath")),
                                orderUuid.toString() + "wx" + ".png");
                        MatrixToImageWriter.writeToPath(bitMatrix, "png", Wxfile.toPath());
                        FileInputStream fileInputStream = new FileInputStream(Wxfile);
                        MultipartFile multipartFile = new MockMultipartFile(Wxfile.getName(),
                                Wxfile.getName(),
                                ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
                        String name = ossutil.uploadImg2Oss(multipartFile);
                        WxUrl = ossutil.getImgUrl(name);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    throw new NullPointerException();
                }
                resultMap.put("ZFBqrUrl", ZFBUrl);
                resultMap.put("WxUrl", WxUrl);
                return ServerResponse.createBySuccess(resultMap);
            case FAILED:
                log.error("支付宝预下单失败!!!");
                return ServerResponse.createByErrorMessage("支付宝预下单失败!!!");

            case UNKNOWN:
                log.error("系统异常，预下单状态未知!!!");
                return ServerResponse.createByErrorMessage("系统异常，预下单状态未知!!!");

            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                return ServerResponse.createByErrorMessage("不支持的交易状态，交易返回异常!!!");
        }
    }

    @Override
    public Integer checkQuotationId(Long quotationId) {
        return orderMapper.checkQuotationId(quotationId);
    }

    @Override
    public ServerResponse jsPay(String orderNo, User user, String ip) throws Exception {
        Order order = orderMapper.selectByUserIdAndOrderNo(orderNo, user.getId());
        String tradeNo = CommonUtils.generateUUID();
        TreeMap<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("appid", PropertiesUtil.getProperty1("wxopen.appid"));
        sortedMap.put("mch_id", weChatConfig.getMchId());
        /*sortedMap.put("device_info", "WEB");*/
        sortedMap.put("nonce_str", CommonUtils.generateUUID());
        sortedMap.put("body", "风水网-订单支付");
        sortedMap.put("out_trade_no", orderNo);
        sortedMap.put("total_fee", String.valueOf(order.getPayment().multiply(new BigDecimal(100)).intValue()));
        sortedMap.put("spbill_create_ip", ip);
        sortedMap.put("notify_url", weChatConfig.getPayCallbackUrl());
        sortedMap.put("openid", user.getOpenid());
        sortedMap.put("trade_type", "JSAPI");
        String sign = WXPayUtil.createSign(sortedMap, weChatConfig.getKey());
        sortedMap.put("sign", sign);
        String payxml = WXPayUtil.mapToXml(sortedMap);
        String orderStr = HttpTools
                .doPost(WeChatConfig.getUnifiedOrderUrl(), payxml, 4000);
        Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
        String prepayId = unifiedOrderMap.get("prepay_id");
        if (StringUtils.isEmpty(prepayId)) {
            ServerResponse.createByErrorMessage("支付错误");
        }
        TreeMap<String, String> finalpackage = new TreeMap<>();
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String s = CommonUtils.generateUUID();
        String packages = "prepay_id=" + prepayId;
        finalpackage.put("appId", PropertiesUtil.getProperty1("wxopen.appid"));
        finalpackage.put("timeStamp", timestamp);
        finalpackage.put("nonceStr", s);
        finalpackage.put("package", packages);
        finalpackage.put("signType", "MD5");
        String finalsign = WXPayUtil.createSign(finalpackage, weChatConfig.getKey());
        HashMap<String, String> rstMap = Maps.newHashMap();
        rstMap.put("appId", weChatConfig.getAppId());
        rstMap.put("timeStamp", timestamp);
        rstMap.put("nonceStr", s);
        rstMap.put("packageValue", packages);
        rstMap.put("paySign", finalsign);
        rstMap.put("total_fee", String.valueOf(order.getPayment().multiply(new BigDecimal(100)).intValue()));
        return ServerResponse.createBySuccess(rstMap);
    }

    //微信小程序付款
  /*  public ServerResponse wxJSPay(HttpServletRequest httpServletRequest) throws Exception {
        User user = Const.checkUserLogin(httpServletRequest);
        String ipAddr = IpUtils.getIpAddr(httpServletRequest);
        //新版需要通过orderCompanyList进行处理
        String tradeNo = CommonUtils.generateUUID();
        TreeMap<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("appid", weChatConfig.getAppId());
        sortedMap.put("mch_id", weChatConfig.getMchId());
        sortedMap.put("device_info", "WEB");
        sortedMap.put("nonce_str", CommonUtils.generateUUID());
        sortedMap.put("body", "CC_PARK");
        sortedMap.put("out_trade_no", tradeNo);
        BigDecimal orderPrice = new BigDecimal("0");
        int price = orderPrice.multiply(new BigDecimal(100)).intValue();
        sortedMap.put("total_fee", String.valueOf(price));
        sortedMap.put("spbill_create_ip", ipAddr);
        sortedMap.put("notify_url", weChatConfig.getPayCallbackUrl());
        sortedMap.put("openid", user.getOpenid());
        sortedMap.put("trade_type", "JSAPI");
        String sign = WXPayUtil.createSign(sortedMap, weChatConfig.getKey());
        sortedMap.put("sign", sign);
        String payxml = WXPayUtil.mapToXml(sortedMap);
        String orderStr = HttpTools
            .doPost(WeChatConfig.getUnifiedOrderUrl(), payxml, 4000);
        Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
        String prepayId = unifiedOrderMap.get("prepay_id");
        if (StringUtils.isEmpty(prepayId)) {
            ServerResponse.createByErrorMessage("支付错误");
        }
        TreeMap<String, String> finalpackage = new TreeMap<>();
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String s = CommonUtils.generateUUID();
        String packages = "prepay_id=" + prepayId;
        finalpackage.put("appId", weChatConfig.getAppId());
        finalpackage.put("timeStamp", timestamp);
        finalpackage.put("nonceStr", s);
        finalpackage.put("package", packages);
        finalpackage.put("signType", "MD5");
        String finalsign = WXPayUtil.createSign(finalpackage, weChatConfig.getKey());
        HashMap<String, String> rstMap = Maps.newHashMap();
        rstMap.put("appId", weChatConfig.getAppId());
        rstMap.put("timeStamp", timestamp);
        rstMap.put("nonceStr", s);
        rstMap.put("packageValue", packages);
        rstMap.put("paySign", finalsign);
        return ServerResponse.createBySuccess(rstMap);
    }*/


}
